home *** CD-ROM | disk | FTP | other *** search
Wrap
/*------------------------------------------------------------------------------ # # MacOS™ Sample Code # # Written by: Eric Anderson # email: eric3@apple.com # # Display Manager sample code # # DisplayVideo # # DisplayVideo.c - C Source # # Copyright © 1995-1999 Apple Computer, Inc. # All rights reserved. # # 1/20/99 ewa Updated to CWPro 3. Added refresh rate, timing flag # and mode flag information # 5/31/95 ewa New today. # # Components: DisplayVideo.c # # DisplayVideo will display all info about all video modes supported by # each installed video card with their attached monitor. # The purpose of this code is to provide a sample of # how developers can change the bit depth and timing of multisync # displays under their own control. # # ------------------------------------------------------------------------------*/ #include <Dialogs.h> #include <Devices.h> #include <Displays.h> #include <Errors.h> #include <FixMath.h> #include <fp.h> #include <Gestalt.h> #include <Memory.h> #include <Palettes.h> #include <PLStringFuncs.h> #include <QuickDraw.h> #include <ROMDefs.h> #include <Slots.h> #include <StdIO.h> #include <Video.h> #include <TextUtils.h> #include <Strings.h> #include <SIOUX.h> #include <iostream> #include <stdlib.h> //-------------------------------------------------------------- // // Internal defines, structs, typedefs, and routine declarations // //-------------------------------------------------------------- struct DepthInfo { VDSwitchInfoRec depthSwitchInfo; // This is the switch mode to choose this timing/depth VPBlock depthVPBlock; // VPBlock (including size, depth and format) }; typedef struct DepthInfo DepthInfo; struct ListIteratorDataRec { unsigned long displayModeFlags; // VDSwitchInfoRec displayModeSwitchInfo; // VDResolutionInfoRec displayModeResolutionInfo; // VDTimingInfoRec displayModeTimingInfo; // Contains timing flags and such unsigned long depthBlockCount; // How many depths available for a particular timing DepthInfo *depthBlocks; // Array of DepthInfo Str255 displayModeName; // name of the timing mode }; typedef struct ListIteratorDataRec ListIteratorDataRec; void PrintCurrentVideoSetting (GDHandle walkDevice); void DisplayVideoSettings (void); void PrintAvailableVideoSettingsDM2 (GDHandle walkDevice, DMDisplayModeListIteratorUPP myModeIteratorProc, DMListIndexType theDisplayModeCount, DMListType *theDisplayModeList); pascal void ModeListIterator ( void *userData, DMListIndexType itemIndex, DMDisplayModeListEntryPtr displaymodeInfo); // routine implementations void main(void) { SIOUXSettings.autocloseonquit = false; SIOUXSettings.asktosaveonclose = false; DisplayVideoSettings (); } //-------------------------------------------------------------- // // Implementation of sample code // //-------------------------------------------------------------- void PrintCurrentVideoSetting (GDHandle walkDevice) { unsigned long displayMgrVersion; OSErr error = paramErr; CntrlParam pBlock; VDSwitchInfoRec switchInfo; AuxDCEHandle theDCE; VDSwitchInfoRec videoMode; Gestalt(gestaltDisplayMgrVers, (long*)&displayMgrVersion); if (displayMgrVersion >= 0x00020000) { // get the info the DM 2.0 way error = DMGetDisplayMode(walkDevice, &switchInfo); if (noErr == error) { printf ("Current Settings DM2 - displayMode: %d, depthMode: %d\n", switchInfo.csData, switchInfo.csMode); } } return; } void DisplayVideoSettings (void) { Boolean displayMgrPresent; short iCount = 0; // just a counter of GDevices we have seen DMDisplayModeListIteratorUPP myModeIteratorProc = nil; // for DM2.0 searches SpBlock spBlock; Boolean suppliedGDevice; DisplayIDType theDisplayID; // for DM2.0 searches DMListIndexType theDisplayModeCount; // for DM2.0 searches DMListType theDisplayModeList; // for DM2.0 searches long value = 0; GDHandle walkDevice = nil; // for everybody Gestalt(gestaltDisplayMgrAttr,&value); displayMgrPresent=value&(1<<gestaltDisplayMgrPresent); displayMgrPresent=displayMgrPresent && (SVersion(&spBlock)==noErr); // need slot manager if (displayMgrPresent) // and Display Manager { walkDevice = DMGetFirstScreenDevice (dmOnlyActiveDisplays); // for everybody suppliedGDevice = false; myModeIteratorProc = NewDMDisplayModeListIteratorProc(ModeListIterator); // for DM2.0 searches // Note that we are hosed if somebody changes the gdevice list behind our backs while we are iterating.... // ...now do the loop if we can start if( walkDevice && myModeIteratorProc) do // start the search { iCount++; // GDevice we are looking at (just a counter) printf("=================================================\n"); printf("GDevice #%d (0x%X) at location (%d,%d).\n",iCount, *walkDevice, (long )(*walkDevice)->gdRect.left, (long )(*walkDevice)->gdRect.top); printf("=================================================\n\n"); PrintCurrentVideoSetting (walkDevice); if( noErr == DMGetDisplayIDByGDevice( walkDevice, &theDisplayID, false ) ) // DM1.0 does not need this, but it fits in the loop { theDisplayModeCount = 0; // for DM2.0 searches if (noErr == DMNewDisplayModeList(theDisplayID, 0, 0, &theDisplayModeCount, &theDisplayModeList) ) { // search video devices the new kool way through Display Manager 2.0 PrintAvailableVideoSettingsDM2 (walkDevice, myModeIteratorProc, theDisplayModeCount, &theDisplayModeList); DMDisposeList(theDisplayModeList); // now toss the lists for this gdevice and go on to the next one } } printf("\n\n\n"); } while ( !suppliedGDevice && nil != (walkDevice = DMGetNextScreenDevice ( walkDevice, dmOnlyActiveDisplays )) ); // go until no more gdevices if( myModeIteratorProc ) DisposeRoutineDescriptor(myModeIteratorProc); return; } } pascal void ModeListIterator(void *userData, DMListIndexType, DMDisplayModeListEntryPtr displaymodeInfo) { unsigned long depthCount; short iCount; ListIteratorDataRec *myIterateData = (ListIteratorDataRec*) userData; DepthInfo *myDepthInfo; long length = 0; // set display data in a round about way // Set the basics myIterateData->displayModeFlags = displaymodeInfo->displayModeFlags; // for mode flags myIterateData->displayModeSwitchInfo = *displaymodeInfo->displayModeSwitchInfo; // not needed - depth info has this per depth myIterateData->displayModeResolutionInfo = *(VDResolutionInfoRec *)displaymodeInfo->displayModeResolutionInfo; // refresh rate, pixels/lines at max depth myIterateData->displayModeTimingInfo = *displaymodeInfo->displayModeTimingInfo; // for iming flags BlockMoveData ((StringPtr)displaymodeInfo->displayModeName,(StringPtr)&myIterateData->displayModeName, ((StringPtr)displaymodeInfo->displayModeName)[0]+1); // the name of the mode // now get the DMDepthInfo into memory we own depthCount = displaymodeInfo->displayModeDepthBlockInfo->depthBlockCount; myDepthInfo = (DepthInfo*)NewPtrClear(depthCount * sizeof(DepthInfo)); // set the info for the caller myIterateData->depthBlockCount = depthCount; myIterateData->depthBlocks = myDepthInfo; // and fill out all the entries if (depthCount) for (iCount=0; iCount < depthCount; iCount++) { myDepthInfo[iCount].depthSwitchInfo = *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthSwitchInfo; myDepthInfo[iCount].depthVPBlock = *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthVPBlock; } } void PrintAvailableVideoSettingsDM2 (GDHandle walkDevice, DMDisplayModeListIteratorUPP myModeIteratorProc, DMListIndexType theDisplayModeCount, DMListType *theDisplayModeList) { short jCount; short kCount; ListIteratorDataRec searchData; double_t refreshRate; unsigned long switchFlags; Boolean modeOk; OSErr error; searchData.depthBlocks = nil; // get the mode lists for this GDevice for (jCount=0; jCount<theDisplayModeCount; jCount++) // get info on all the resolution timings { DMGetIndexedDisplayModeFromList(*theDisplayModeList, jCount, 0, myModeIteratorProc, &searchData); // for all the depths for this resolution timing (mode)... printf("\nTiming mode: %d (or 0x%X) named “%s”\n", searchData.depthBlocks[0].depthSwitchInfo.csData, searchData.depthBlocks[0].depthSwitchInfo.csData, P2CStr(searchData.displayModeName)); refreshRate = Fix2X (searchData.displayModeResolutionInfo.csRefreshRate); if ( round (refreshRate) == 0) printf ("Refresh rate: 0 (not defined in displayModeResolutionInfo.csRefreshRate)\n"); else { Str255 refreshStr; decform theFormat; decimal theNumeric; theFormat.style = FIXEDDECIMAL; theFormat.unused = 0; theFormat.digits = 4; num2dec (&theFormat, refreshRate, &theNumeric ); dec2str ( &theFormat, &theNumeric, (char *)refreshStr ); printf ("Refresh rate: %s\n", refreshStr); } if (searchData.displayModeResolutionInfo.csResolutionFlags & 1<<kResolutionHasMultipleDepthSizes) printf("DisplayMode has different H&V per bit depth\n"); { char tempArr[6]; ResType* tempPtr = (ResType* )&tempArr[0]; // Make a convenient ptr to assign the restype *tempPtr = searchData.displayModeTimingInfo.csTimingFormat; // contents of string are the resType tempArr[4] = 0; // null temp the string printf("Timing format: “%s”. Timing csData %d\n", tempArr, searchData.displayModeTimingInfo.csTimingData); } printf("Available depths:\n"); if (searchData.depthBlockCount) for (kCount = 0; kCount < searchData.depthBlockCount; kCount++) { // print all the timing information printf(" Depth: %d, Depth mode: 0x%X, Resolution: %dH x %dV\n", searchData.depthBlocks[kCount].depthVPBlock.vpPixelSize, searchData.depthBlocks[kCount].depthSwitchInfo.csMode, searchData.depthBlocks[kCount].depthVPBlock.vpBounds.right, searchData.depthBlocks[kCount].depthVPBlock.vpBounds.bottom); // printf("Components per Pixel: %d, bits per Component: %d\n", // searchData.depthBlocks[kCount].depthVPBlock.vpCmpCount, // searchData.depthBlocks[kCount].depthVPBlock.vpCmpSize); } // Switch Flags error = DMCheckDisplayMode(walkDevice, searchData.depthBlocks[0].depthSwitchInfo.csData, searchData.depthBlocks[0].depthSwitchInfo.csMode, &switchFlags, 0, &modeOk); if (noErr == error && modeOk) { printf("Switch Flags = 0x%X\n", switchFlags); // if (switchFlags & 1<<kNoSwitchConfirmBit) // printf(" Confirmation not required,\n"); // else printf(" Confirmation required,\n"); // if (switchFlags & 1<<kDepthNotAvailableBit) // printf(" Current depth not available in this mode,\n"); // else printf(" Current depth available in this mode,\n"); // if (switchFlags & 1<<kShowModeBit) // printf(" Always shown,\n"); // else printf(" Not always shown,\n"); // if (switchFlags & 1<<kModeNotResizeBit) // printf(" Not resizeable,\n"); // else printf(" Resizeable\n"); } // Timing Flags printf("Timing Flags = 0x%X\n",searchData.displayModeTimingInfo.csTimingFlags); if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeValid) printf(" Valid,\n",searchData.displayModeTimingInfo.csTimingFlags); else printf(" Invalid,\n",searchData.displayModeTimingInfo.csTimingFlags); if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeSafe) printf(" Safe,\n"); else printf(" Unsafe,\n"); if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeDefault) printf(" Default,\n"); else printf(" Not default,\n"); if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeShowNow) printf(" Always shown,\n"); else printf(" Not always shown,\n"); // if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeNotResize) // printf(" Not resizeable,\n"); // else printf(" Resizeable,\n"); // if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeRequiresPan) // printf(" Requires pan.\n"); // else printf(" No pan.\n"); if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeInterlaced) printf(" Interlaced.\n"); // Mode Flags printf("Mode Flags = 0x%X\n",searchData.displayModeFlags); if (searchData.displayModeFlags & 1<<0) printf(" Stripped,\n"); // does not show up in "Recomended" list of timings else printf(" Not Stripped,\n"); // Is a recomended timing if (searchData.depthBlocks) { DisposePtr ((Ptr)searchData.depthBlocks); // toss for this timing mode of this gdevice searchData.depthBlocks = nil; // init it just so we know } } }